##
#
# Snaarpy: Guitar chord parser and formatter
# Copyright (C) 2009 Alberto Gonzalez
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
##

from snaarpy.output import OutputFileWriter
from snaarpy.chordutils import *

import sys
import codecs
import latexcodec

_latex_preamble = r'''
\documentclass[a4paper]{article}

\usepackage{makeidx}
\makeindex

\usepackage{multicol}
\setlength{\columnseprule}{0pt}
\setlength{\columnsep}{1cm}

\usepackage[noheadfoot,margin=1cm]{geometry}
\setlength{\parindent}{0pt}

\usepackage{gchords}

%% Chord Macros
\def\sbChord#1{% 
  \ifx#1\relax% 
    \let\next=\relax% 
  \else% 
    \ifx#1##% double sharp because we're inside a \def 
      $\sharp$% 
    \else% 
      \ifx#1b% 
        $\flat$% 
      \else% 
        \ifx#1/% 
          \small/% 
        \else% 
          \ifx#1[% 
            \bgroup [\egroup% 
          \else% 
            \ifx#1]% 
              \bgroup ]\egroup% 
            \else% 
              #1% 
            \fi% 
          \fi% 
        \fi% 
      \fi% 
    \fi% 
    \let\next=\sbChord% 
  \fi% 
  \next% 
} 

\newlength{\newcwidth}%

\newcommand{\Cn}[1]{{\sffamily\bfseries\sbChord#1\relax}}

\newcommand{\Ch}[2]{{%
  \setbox1=\hbox{\sffamily\bfseries\sbChord#1\relax\strut}% 
  \setbox0=\hbox{#2}% 
  \ifdim\wd1<\wd0% 
    \strut\raise2.25ex\copy1\kern-\wd1\copy0% 
  \else% 
    \strut\copy0\kern-\wd0\strut\raise2.25ex\copy1% 
  \fi% 
}}


\newcommand{\HeadRule}{\makebox[0pt][l]{\rule[-5pt]{\textwidth}{0.4pt}}}
% Song environment
\newenvironment{song}[2]{%
    \newpage\index{#2!#1}%
    \setlength{\parskip}{1ex}%
    \HeadRule{\LARGE\bfseries #1 \hfill \itshape #2} \par%
}{}
        
\newcommand{\chorus}[1]{%
    \hspace*{.5cm}%
    \parbox{\linewidth}{#1}%
}
        
\newcommand{\comment}[1]{%
    \footnotesize{#1}
}

\newenvironment{vgroup}[1]{% 
  \hspace{-1em}{\itshape #1:} \obeylines%
}{%  
}

%\def\obeyspaces{\catcode`\ =\active}
%{\obeyspaces\global\let =\space}
{\catcode`\^^M=\active % these lines must end with '%'
\gdef\obeylines{\catcode`\^^M=\active \let^^M=\retline}%
\global\let^^M=\retline} % this is in case ^^M appears in a \write

\def\retline{\\}


\begin{document}

'''

_song_begin = r'''\begin{song}{%s}{%s}
'''

_song_body = r'''
\vspace{1em}
\begin{multicols}{2}
'''

_song_end = r'''\end{multicols}
\end{song}
'''

_group_begin = r'''
\begin{vgroup}{%s}
'''

_group_end = r'''\end{vgroup}
'''

_latex_end = r'''
\printindex
\end{document}
'''

def gchord(chord, frets, base = 't'):
        spec = []
        for c in frets:
            if c in "xX":
                spec.append('x')
            elif c in "123456789":
                spec.append('p%s' % c)
            elif c == "0":
                spec.append('o')
        fingers = ",".join(spec)
        if base == 0:
            base = 't'
        else:
            base = base + 1
        return r"\chord{%s}{%s}{\sbChord %s\relax}" % (base, fingers, chord)


class LatexFileWriter(OutputFileWriter):
    extension = "tex"
    description = "LaTeX file output filter"
    
    def __init__(self, out_name):
        OutputFileWriter.__init__(self, out_name)
        self._lt = codecs.getencoder('latex')        
    
    def beginOutput(self):
        if self.out_name == None:
            self.outf = sys.stdout
        elif isinstance(self.out_name, basestring):
            self.outf = file(self.out_name, 'w')
        else:
            self.outf = self.out_name
        self.outf.write(_latex_preamble)
    
    def beginSong(self, song):
        self.outf.write(_song_begin % (self._lt(song.title)[0], self._lt(song.author)[0]))
        if song.capo:
            self.outf.write('{\hfill Capo %s \hfill}\n' % self._lt(song.capo)[0])
        self.outf.write(r'\vspace{1em}')
    
    def songChords(self, chords):
        self.outf.write(r'\chords{')
        for ch in sorted(chords, key=lambda x: x.short):
            if ch.frets:
                base = find_base_fret(ch.frets)
                texfrets = gchord(ch.short, correct_base_fret(ch.frets, base), base)
                self.outf.write(texfrets)
        self.outf.write(r'}')
    
    def beginSongBody(self, song):
        self.outf.write(_song_body)

    def endSong(self, song):
        self.outf.write(_song_end)
    
    def beginGroup(self, group):
        self.outf.write(_group_begin % self._lt(group.label.title())[0])
        if len(group.verses) > 0:
            self.last_v = group.verses[-1]
        else:
            self.last_v = None
        
    def endGroup(self, group):
        self.outf.write(_group_end)
        
    def text(self, text):
        self.outf.write(self._lt(text.text)[0])
    
    def chordUse(self, use, over_text):
        if over_text:
            if use.word == '':
                self.outf.write(' ')
            self.outf.write(r'\Ch{%s}{%s}' % (use.chord.short, self._lt(use.word)[0]))
            #if use.word == '':
            #    self.outf.write(' ')
        else:
            self.outf.write(r'\Cn{%s} ' % use.chord.short)
    
    def endInstrumental(self, instrumental):
        #if self.last_v != instrumental:
        #    self.outf.write(r'\\')
        self.outf.write('\n')
    
    def endVerse(self, verse):
        #if self.last_v != verse:
        #    self.outf.write(r'\\')
        self.outf.write('\n')   
         
    def endOutput(self):
        self.outf.write(_latex_end)
        self.outf.close()

